import auth.AuthManager;
import factory.PassingParametersFactory;
import factory.SingleSqlParserFactory;
import function.CreateIndex;
import function.IsLegal;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

//使用了工厂模式来创建解析器和处理参数，以及使用XML文件来存储用户信息和帮助信息。
public class Main {

    public static void main(String[] args) throws DocumentException, IOException {


        System.out.println("欢迎进入My-Simple-Dbms,请先登录");

        //声明一个变量a，记录用户输入错误次数，超过3此则退出系统
        int a = 3;

        while (a > 0) {
            if (AuthManager.authenticate()) {
                System.out.println("登录成功");
                a = 0;
            } else {
                System.out.println("用户名或密码错误，请重试");
                a--;
                if (a == 0) {
                    System.out.println("输入用户名/密码错误3次，系统即将退出");
                    return;
                }
            }
        }

        //加载索引文件到内存
        if (IsLegal.need_loadIndex()) {
            CreateIndex.loadIndex();
        }

        while (true) {
            System.out.println("请输入SQL语句   (输入help查看帮助)");
            System.out.print("以分号结尾:    ");
            Scanner input = new Scanner(System.in);
            String sql = input.nextLine();
            /*
             * 预处理:获得语句;
             * 处理前后空格;
             * 变小写;
             * 处理中间多余的空格回车和特殊字符;
             * 在末尾加特殊符号;
             * 处理掉最后的;
             */
            if (sql.equals("help")) {
                read_help();
                System.out.println();
                continue;
            }
            //没有分号,前值为-1;该判断为true表示没有分号;
            if (sql.lastIndexOf(";") != sql.length() - 1) {
                System.out.println("输入错误!   没有分号");
                System.out.println();
                continue;
            }
            //对用户输入的SQL语句进行预处理，包括去除前后空格、转换为小写、替换多余的空格、截取最后一个分号前的所有内容，以及在末尾添加ENDOFSQL标记。
            sql = sql.trim();
            sql = sql.toLowerCase();
            sql = sql.replaceAll("\\s+", " ");

            if (sql.endsWith(";")) {
                sql = sql.substring(0, sql.length() - 1);
            }
            sql = sql + " ENDOFSQL";
            System.out.println("1)SQL预处理结果: " + sql);

            List<List<String>> parameter_list = new ArrayList<List<String>>();

            //  用户输入  'quit;' 退出程序
            if (sql.equals("quit ENDOFSQL")) return;

            else {
                //将预处理后的SQL语句匹配SQL正则表达式，返回含有SQL的body信息的List
                try {
                    parameter_list = SingleSqlParserFactory.generateParser(sql);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //根据SQL的body部分，调用相应的功能模块
                try {
                    if (parameter_list != null) {
                        //检测权限
                        String permission = parameter_list.get(0).get(0).split("\\s+")[0];
                        if (!AuthManager.hasPermission(permission)) {
                            System.out.println("缺少权限!");
                            System.out.println();
                            continue;
                        }
                        PassingParametersFactory.dealParameters(parameter_list);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            System.out.println();
        }
    }


    public static void read_help() throws DocumentException {
        String userDir = System.getProperty("user.dir");
        File file = new File(userDir, "help.xml");  //从根目录开始读取
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read(file);
        List<Node> nodes = document.getRootElement().selectNodes("help");
        for (Node node : nodes) {
            Element element = (Element) node;
            System.out.println(element.getText());
        }
    }


}
